package com.jketing.controller.ams.base;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.jketing.Config;
import com.jketing.bean.PageBean;
import com.jketing.controller.BaseController;
import com.jketing.entity.ams.base.Employee;
import com.jketing.entity.ams.base.Organ;
import com.jketing.service.ams.base.EmployeeService;
import com.jketing.service.ams.base.OrganService;
import com.jketing.service.ams.sys.DictionaryService;

/**
 * Controller 请求处理
 * 
 * @author  李荣华
 * @version v1.0
 * @date    2017-11-22
 * @since   Spring-mvc 4.3.8
 */
@Controller
@RequestMapping("/employee")
public class EmployeeController extends BaseController{

	/**
	 *  service 	服务层自动注入
	 */
	@Autowired
	private EmployeeService service;
	/**
	 *  service 	服务层自动注入
	 */
	@Autowired
	private OrganService os;
	/**
	 *  service 	服务层自动注入
	 */
	@Autowired
	private DictionaryService ds;
	
	/*@InitBinder
	public void initBinder(WebDataBinder binder){
		binder.setDisallowedFields("lastName");
	}*/
	
	/**
	 * 打开单选对话框
	 * 
	 * @return 返回跳转标志singleSelect
	 */
	@RequestMapping(value="/singleSelect",method=RequestMethod.GET)
	public String singleSelect(Map<String, Object> map) {		
		List<Organ> list = os.getOrganList("unit");//加载单位列表
		map.put("list", list);
		map.put("topTree",os.getTree(service.getRootId()).toString());
		return "dialog/employee/singleSelect";		
	}
	
	/**
	 * 打开多选对话框
	 * 
	 * @return 返回跳转标志multiSelect
	 */
	@RequestMapping(value="/multiSelect",method=RequestMethod.GET)
	public String multiSelect(Map<String, Object> map) {		
		List<Organ> list = os.getOrganList("unit");//加载单位列表
		map.put("list", list);
		map.put("topTree",os.getTree(service.getRootId()).toString());
		return "dialog/employee/multiSelect";		
	}
	
	/**
	 *  getEmployeeList 得到查询运算符
	 *  
	 *  ResponseBody注解直接向客户端返回Map,框架自动转化为json
	 *  
	 *  @return List<Employee>
	 */
	@RequestMapping(value="/getEmployeeList",method=RequestMethod.GET)
	@ResponseBody
    public List<Employee> getEmployeeList(String organId){
    	return os.getEmployeeList(organId);
    }
	
	/**
	 *  getOperateSelect 得到查询运算符
	 *  
	 *  ResponseBody注解直接向客户端返回Map,框架自动转化为json
	 *  
	 *  @return Map<String,String>
	 */
	@RequestMapping(value="/getOperateSelect",method=RequestMethod.GET)
	@ResponseBody
	public Map<String,String> getOperateSelect(String type){
		Map<String,String> map = findOperators();
		if("String".equals(type)){
			map = findOperatorsForString();
		}
		return map;
	}
	
	/**
	 *  getImage 得到图片二进制内容
	 *  
	 *  ResponseBody注解直接向客户端返回byte数组,框架自动转化为二进制流
	 *  
	 *  @param	String id:pk
	 *  
	 *  @return byte[]
	 */
	@RequestMapping(value="/getImage/{id}",method=RequestMethod.GET)
	@ResponseBody
	public byte[] getImage(@PathVariable("id") String id){
		Employee entity = service.findOne(id);
		return entity.getPhoto();
	}
	
	/**
	 *  @ModelAttribute方法 	得到实体数据放入Request
	 *  功能:在更新数据时，若只是提交了实体的部分数据，没有此方法直接更新将丢失表单没提交的数据，
	 *  为了防止未提交数据丢失，提供如下功能：
	 *  1、此方法先从数据库读取一次对象数据放入请求域；
	 *  2、待更新表单提交更新数据时，Srping-MVC会从请求域拿出此对象和表单提交数据合并后以入参方式传给目标方法
	 *  3、目标方法拿到最后合并的对象，调用service的更新方法更新数据库
	 *  4、此方法由Srping-MVC自动调用
	 * 	 
	 *  @param 	String		id		实体id		
	 *  @param  Map<String, Object>	map	Request数据键值对影射
	 *  
	 *  @return void
	 */
	@ModelAttribute
	public void getEmployee(@RequestParam(value="id",required=false) 
							String id,
							Map<String, Object> map){
		if(id != null){//在有id时查数据库 
			Employee entity = service.findOne(id);
			//若实体的关联对象要变更，如有员工实体引用了部门实体，在员工编辑页修改了部门提交；
			//在此要将员工关联部门对象设为null,不为null调用员工更新方法将报错；
			//调用形式：employee.setEmployee(null);
			//此处增加设null关联对象代码
			
			//1.map的key在默认情况下，必顺为要存值类名第一个字母小写的名称；
			//2.如这里entity类型是Employee类，其key名必为：employee
			//3.除非在目标方法入参前加有@ModelAttribute修饰，并设置了value值名称，可用其它名
			map.put("employee", entity);
		}
	}
	
	/**
	 *  list 处理多条件查询分页排序请求
	 *  @param	String  flag	区分进入列表还是框架
	 *  @param	String  nodeId	点击的树型节点id,这里为部门id
	 *  @param	String	query	查询条件字符串表达式
	 *  @param	String	order	排序字段名
	 *  @param 	String	page	页码
	 *  @param  HttpSession session	注入原生API
	 *  @param  Map<String, Object>	map	模型数据返回
	 *  
	 *  @return String	返回页面路径
	 * @throws JsonProcessingException 
	 */
	@RequestMapping("/list")
	public String list(String flag,
					   String nodeId,
					   String query,
	   				   @RequestParam(value="order", 
				       required=false, 
				       defaultValue="id desc") 
					   String order,
					   String page,
					   HttpSession session,  
					   Map<String, Object> map) throws JsonProcessingException{
		if("list".equals(flag)){
			String type = (String)session.getAttribute("type");
			if("redirect".equals(type)) {
				map.put("type", type);
				nodeId = session.getAttribute("nodeId")!=null?session.getAttribute("nodeId").toString():null;
				query = session.getAttribute("query")!=null?session.getAttribute("query").toString():null;
				order = session.getAttribute("order")!=null?session.getAttribute("order").toString():null;
				page = session.getAttribute("page")!=null?session.getAttribute("page").toString():null;
				session.removeAttribute("type");
				session.removeAttribute("nodeId");
				session.removeAttribute("query");
				session.removeAttribute("order");
				session.removeAttribute("page");
			}
			int pageNo = 1;
			try {
				//对 pageNo 的校验
				pageNo = Integer.parseInt(page);
				if(pageNo < 1){
					pageNo = 1;
				}
			} catch (Exception e) {}
			map.put("flag", flag);
			map.put("nodeId", nodeId);
			map.put("order", order);
			map.put("page", page);
			map.put("vQuery", 0);
			//map.put("unitNature", ds.getPropertyByEnName("unitNature"));
			//map.put("subOrdination", ds.getPropertyByEnName("subOrdination"));
			//map.put("classifyToManage", ds.getPropertyByEnName("classifyToManage"));
			//query = "[String:name:X%:张]|[Entity:qualification:String:name:=:技术员]&[String:cardId:%X%:5322]|([Entity:scholar:String:name:=:本科]|[String:speciality:=:生物])&[String:school:=:云南大学]#";
			map.put("query", query);
			map.put("queryFields", toJson(findQueryFields(Employee.class)));
			PageBean<Employee> pageBean = null;			
			if(StringUtils.isNotBlank(query)) {
				//query = "[Entity:organSet:Entity:unitNature:String:enName:=:unit]#";
				query = query.replace("#", "");
				query = "[Entity:organs:String:id:=:" + nodeId + "]&(" + query + ")#";
			}else {
				query = "[Entity:organs:String:id:=:" + nodeId + "]#";
			}
			System.out.println("================query:" + query);
			pageBean = service.getPageBean(query,order,pageNo,Config.getPageSize());
			map.put("pageBean", pageBean);
			return "base/employee/list";
		}else{
			String rootId = service.getRootId();
			map.put("rootId", rootId);
			List<Organ> list = os.getOrganList("unit");//加载单位列表
			map.put("list", list);
			map.put("topTree", os.getTree(rootId).toString());//加载从id为1的根节点开始
			return "base/employee/listFrame";
		}
	}
	
	/**
	 *  getQueryFields 得到实体动态查询字段
	 *  
	 *  ResponseBody注解直接向客户端返回Map,框架自动转化为json
	 *  
	 *  @return Map<String,String>
	 */
	@RequestMapping(value="/getQueryFields",method=RequestMethod.GET)
	@ResponseBody
	public Map<String,String> getQueryFields(){
		return findQueryFields(Employee.class);
	}
	
	/**
	 *  input 进入新增编辑页
	 *  REST风格获取URL：employee/，GET请求
	 *  
	 *  @param	Map<String, Object>	map	页面数据返回
	 *  
	 *  @return	String	返回页面路径
	 */
	@RequestMapping(method=RequestMethod.GET)
	public String input(String nodeId,
						String query,
						String order,
						HttpSession session,
						Map<String,Object> map){		
		Employee entity = new Employee();		
		map.put("entity", entity);
		map.put("sex", ds.getPropertyByEnName("sex"));
		map.put("nation", ds.getPropertyByEnName("nation"));
		map.put("cardType", ds.getPropertyByEnName("cardType"));
		map.put("educationalBackground", ds.getPropertyByEnName("educationBackground"));
		map.put("qualification", ds.getPropertyByEnName("qualification"));
		map.put("duty", ds.getPropertyByEnName("duty"));
		map.put("ids", nodeId);
		map.put("names", os.findOne(nodeId).getName());
		session.setAttribute("type", "redirect");
		session.setAttribute("nodeId", nodeId);
		session.setAttribute("query", query);
		session.setAttribute("order", order);
		return "base/employee/edit";
	}
	
	/**
	 *  input	进入更新编辑页
	 *  REST风格获取URL：employee/{id}，GET请求改为POST请求，因在进入更新页时要接收查询表单条件
	 *  @param	Map<String, Object>	map	页面数据返回
	 *  
	 *  @return	String	返回页面路径
	 */
	@RequestMapping(value="/{id}", method=RequestMethod.GET)
	public String input(@PathVariable("id") String id,
						String nodeId,			
						String query,
						String order,
						String page,
						HttpSession session,
						Map<String, Object> map){
		Employee entity = service.findOne(id);
		map.put("entity", entity);
		map.put("sex", ds.getPropertyByEnName("sex"));
		map.put("nation", ds.getPropertyByEnName("nation"));
		map.put("cardType", ds.getPropertyByEnName("cardType"));
		map.put("educationalBackground", ds.getPropertyByEnName("educationBackground"));
		map.put("qualification", ds.getPropertyByEnName("qualification"));
		map.put("duty", ds.getPropertyByEnName("duty"));
		map.put("organs",service.getOrgans(id));
		//因更新后会重定向到列表，使用session保存翻页条件在多个请求中共享数据
		session.setAttribute("type", "redirect");
		session.setAttribute("nodeId", nodeId);
		session.setAttribute("query", query);
		session.setAttribute("order", order);
		session.setAttribute("page", page);
		return "base/employee/edit";
	}
	
	/**
	 *  save	保存实体
	 *  REST风格新增URL：employee/，POST请求
	 *  
	 *  @param	Employee	entity	接收页面提交数据封装实体
	 *  
	 *  @return	String	返回页面路径
	 * @throws IOException 
	 */
	@RequestMapping(method=RequestMethod.POST)
	public String save(String ids,Employee entity,MultipartFile file) throws IOException{
		if(file.getSize()>0) {
			entity.setPhoto(getPhotoBytes(file, 512, 1027, 768));
		}
		service.save(entity,ids);
		return "redirect:/employee/list?flag=list";
	}
	
	/**
	 *  update	更新实体
	 *  REST风格更新URL：employee/{id}，PUT请求
	 *  
	 *  @param	Employee	entity	接收页面提交数据封装实体
	 *  
	 *  @return	String	返回页面路径
	 */
	@RequestMapping(value="/{id}",method=RequestMethod.PUT)
	public String update(String ids,Employee entity,MultipartFile file) throws IOException{
		if(file.getSize()>0) {
			entity.setPhoto(getPhotoBytes(file, 512, 1027, 768));
		}
		service.update(entity,ids);
		return "redirect:/employee/list?flag=list";
	}
	
	/**
	 *  delete	删除实体
	 *  REST风格删除URL：employee/{id}，DELETE请求
	 *  
	 *  @param	Employee	entity	接收页面提交数据封装实体
	 *  
	 *  @return	String	返回页面路径
	 */
	@RequestMapping(value="/{ids}",method=RequestMethod.DELETE)
	public String delete(@PathVariable("ids") String ids,
						String nodeId,	
						String query,
						String order,
						String page,
						HttpSession session){
		if(StringUtils.isNoneBlank(ids)){
			String[] array = ids.split(",");
			for(int i=0;i<array.length;i++){
				service.delete(array[i]);
			}
		}
		//因是重定向到列表，使用session保存翻页条件在多个请求中共享数据
		session.setAttribute("type", "redirect");
		session.setAttribute("nodeId", nodeId);
		session.setAttribute("query", query);
		session.setAttribute("order", order);
		session.setAttribute("page", page);
		return "redirect:/employee/list?flag=list";
	}
}
